use super::Tomlable;

use serde::{Deserialize, Serialize};
use std::fs;
use std::io;
use std::path::{Path, PathBuf};

#[derive(Debug, Serialize, Deserialize)]
pub struct TrainConf {
  pub lang: String,
  pub font: String,
  // 迭代次数
  pub num: usize,
}

impl TrainConf {
  pub fn new(lang: String, font: String) -> Self {
    TrainConf { lang, font, num: 0 }
  }

  pub fn plus_num(&mut self) {
    self.num = self.num + 1;
  }

  pub fn dir<P>(&self, train_base_dir: P) -> PathBuf
  where
    P: AsRef<Path>,
  {
    Self::resolve_dir(train_base_dir, &self.lang, &self.font)
  }

  pub fn resolve_dir<P>(train_base_dir: P, lang: &str, font: &str) -> PathBuf
  where
    P: AsRef<Path>,
  {
    let mut train_dir = PathBuf::from(train_base_dir.as_ref());
    train_dir.push(format!("{}-{}", lang, font));
    train_dir
  }
}

impl<'a, P> Tomlable<'a, P> for TrainConf
where
  P: AsRef<Path>,
{
  fn write_to_toml(&self, to_location: P, overridable: bool) -> io::Result<()> {
    let config_file = to_location.as_ref();
    if !config_file.exists() || overridable {
      let action = iif!(!overridable, "创建", "覆盖");
      println!("{}train配置文件...", action);
      let dir = config_file.parent().unwrap();
      if !dir.exists() {
        if let Ok(_) = fs::create_dir_all(dir) {
        } else {
          eprintln!("can't mkdir<{}>", dir.display());
        }
      }
      let toml = toml::to_string(self).unwrap();
      if let Ok(_) = fs::write(config_file, toml) {
        println!(
          "==成功{}train配置文件`{}`==",
          action,
          config_file.file_name().unwrap().to_str().unwrap()
        );
      } else {
        eprintln!("can't save .toml in the path<{}>", config_file.display());
      }
    } else {
      println!(
        "==已检测到`{}.{}.toml`配置文件,跳过==",
        self.lang, self.font
      );
    }

    Ok(())
  }
  fn read_from_toml(from_location: P) -> io::Result<Self> {
    let content = fs::read_to_string(from_location.as_ref())?;
    let train_conf = toml::from_str::<Self>(&content);

    match train_conf {
      Ok(train_conf) => Ok(train_conf),
      Err(err) => {
        eprint!("err=>{}", err);
        panic!(
          "无法找到train配置文件<{}>",
          from_location.as_ref().display()
        );
      }
    }
  }
}
